package org.example.ag_notes.service;

import org.example.ag_notes.dto.article.TagDTO;
import org.example.ag_notes.dto.article.articleDto;
import org.example.ag_notes.dto.response.Response;
import org.example.ag_notes.entity.Article;
import org.example.ag_notes.entity.Tag;
import org.example.ag_notes.entity.User;
import org.example.ag_notes.exception.BusinessException;
import org.example.ag_notes.repository.ArticleRepository;
import org.example.ag_notes.repository.TagRepository;
import org.example.ag_notes.repository.UserRepository;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.transform.sax.SAXResult;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class ArticleService extends BaseService {

    private final ArticleRepository articleRepository;
    private final UserRepository userRepository;
    //引入AuthService用于token校验
    private final AuthService authService;
    private final TagRepository tagRepository;

    @Autowired
    public ArticleService(ArticleRepository articleRepository, UserRepository userRepository, AuthService authService, TagRepository tagRepository) {
        this.articleRepository = articleRepository;
        this.userRepository = userRepository;
        this.authService = authService;
        this.tagRepository = tagRepository;
    }

    //添加文章
    /**
     * 添加文章
     * @param article 文章内容（需包含title/content/tag等字段）
     * @param token JWT访问令牌
     * @return 包含新文章的响应
     */
    public Article addArticle(Article article, String token) {
            User author = validateAndGetUser(token);


            article.setAuthor(author);
            // 7. 保存文章
            Article savedArticle = articleRepository.save(article);
            // 8. 返回成功响应
            return savedArticle;
    }


    /**
     * 获取用户文章列表（基础版，不分页）
     * @param token JWT访问令牌
     * @return 文章列表
     */
    public List<articleDto> getArticlesByUser(String token) {
            User user = validateAndGetUser(token);

            //根据uid找到文章列表
            List<Article> articles = articleRepository.findByAuthorId(user.getId());
            //转换成dto
            List<articleDto> ats = new ArrayList<>();
            for(Article article : articles){
                articleDto dto = new articleDto(article.getId(), article.getTitle(),article.getContent(),article.getDate(),article.getTag());
                ats.add(dto);
            }
            return ats;
    }

    /**
     * 根据id更新文章的内容
     * @param article
     * @param token
     * @return
     */
    // 实现更新文章方法
    public Response<Article> updateArticle(Article article, String token) {
            User user = validateAndGetUser(token);

            // 3. 验证文章是否存在且属于当前用户
            Article existingArticle = articleRepository.findById(article.getId())
                    .orElseThrow(() -> new BusinessException("文章不存在"));

            if (!existingArticle.getAuthor().getId().equals(user.getId())) {
                return Response.error(403, "无权修改此文章");
            }

            // 4. 更新字段
            existingArticle.setTitle(article.getTitle());
            existingArticle.setContent(article.getContent());
            existingArticle.setTag(article.getTag());
            if (article.getDate() != null) {
                existingArticle.setDate(article.getDate());
            }

            // 5. 保存更新
            Article updatedArticle = articleRepository.save(existingArticle);
            return Response.success("文章更新成功", updatedArticle);
    }

    //删除文章
    /**
     * 删除文章
     * @param articleId 文章ID
     * @param token JWT访问令牌
     * @return 操作结果
     */
    public Response<Void> deleteArticle(Integer articleId, String token) {
            User user = validateAndGetUser(token);
            // 2. 验证文章是否存在且属于当前用户
            Article existingArticle = articleRepository.findById(articleId)
                    .orElseThrow(() -> new BusinessException("文章不存在"));

            if (!existingArticle.getAuthor().getId().equals(user.getId())) {
                return Response.error(403, "无权删除此文章");
            }

            // 3. 执行删除
            articleRepository.delete(existingArticle);
            return Response.success("文章删除成功", null);
    }


    public articleDto getArticleById(Integer id , String token) {
        User user = validateAndGetUser(token);
        Article article = articleRepository.findById(id).orElseThrow(() -> new BusinessException("<UNK>"));
        return new articleDto(article.getId(), article.getTitle(),article.getContent(),article.getDate(),article.getTag());
    }

    /**
     * 添加标签到文章
     * @param articleId
     * @param tagName
     * @param token
     *
     */
    @Transactional
    public void addTagToArticle(Integer articleId, String tagName, String token) {
        User user = validateAndGetUser(token);

        // 使用JOIN FETCH避免懒加载问题
        Article article = articleRepository.findByIdWithTags(articleId)
                .orElseThrow(() -> new RuntimeException("Article not found"));

        Tag tag = tagRepository.findByName(tagName)
                .orElseGet(() -> {
                    Tag newTag = new Tag(tagName);
                    return tagRepository.save(newTag);
                });

        // 使用安全的方法添加标签
        article.addTag(tag);

        // 不需要手动save，@Transactional会自动flush
    }

    //获取文章的所有标签
    /**
     * 获取文章的所有标签
     * @param articleId 文章ID
     * @param token 用户令牌（用于权限校验）
     * @return 标签集合
     */
    @Transactional(readOnly = true)
    public List<TagDTO> getArticleTags(Integer articleId, String token) {
        // 验证用户
        validateAndGetUser(token);

        // 获取标签
        Set<Tag> tags = articleRepository.findTagsByArticleId(articleId);

        // 转换为DTO
        return tags.stream()
                .map(TagDTO::fromEntity)
                .collect(Collectors.toList());
    }
}

